/******************************************************
 * @file freetype.c
 * @author Destiny 
 * @brief freetype字体引擎库
 * 
 * @version 0.1
 * @date 2024-07-18
 *****************************************************/
#include <config.h>
#include <fonts_manager.h>
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_GLYPH_H



static int FreeTypeFontInit(char *pcFontFile, uint32_t dwFontSize);    /*freetype初始化*/
static int FreeTypeGetFontBitmap(uint32_t dwCode, PT_FontBitMap ptFontBitMap);   /*获得字体位图数据*/
static void FreeTypeSetFontSize(uint32_t dwFontSize);             /*设置字体大小*/
/*构造字体操作结构体*/
static T_FontOpr g_tFreeTypeFontOpr = {
	.name          = "freetype",
	.FontInit      = FreeTypeFontInit,
	.GetFontBitmap = FreeTypeGetFontBitmap,
	.SetFontSize   = FreeTypeSetFontSize,
};

static FT_Library g_tLibrary;  /*一个 FreeType 库的实例*/
static FT_Face g_tFace;        /*一个字体的实例，用于加载和存储字体文件的信息*/
static FT_GlyphSlot g_tSlot;   /*用于存储字符轮廓信息的数据结构*/

/*
 * @description		    	: Freetype字体初始化
 * @param - pcFontFile		: FreeType字库文件
 * @param - dwFontSize		: 字体大小
 * @return 			    	: 0 成功;其他 失败
 */
static int FreeTypeFontInit(char *pcFontFile, uint32_t dwFontSize)
{
	int iError;

	/* 初始化Freetype库 */
	iError = FT_Init_FreeType(&g_tLibrary );			   
	if (iError)
	{
		DBG_PRINTF(DLOG_LVL_ERROR,DLOG_TAG,"FT_Init_FreeType failed\n");
		return -1;
	}
	/* 加载字体文件 */
	iError = FT_New_Face(g_tLibrary, pcFontFile, 0, &g_tFace); 
	if (iError)
	{
		DBG_PRINTF(DLOG_LVL_ERROR,DLOG_TAG,"FT_Init_FreeType failed\n");		
		return -2;
	}
	g_tSlot = g_tFace->glyph;
	/* 设置字符的像素大小 */
	iError = FT_Set_Pixel_Sizes(g_tFace, dwFontSize, 0);
	if (iError)
	{
		DBG_PRINTF(DLOG_LVL_ERROR,DLOG_TAG,"FT_Set_Pixel_Sizes failed : %d\n", dwFontSize);
		return -3;
	}	
	return 0;
}
/*
 * @description		    	: 获得UNICODE字符的Freetype位图
 * @param - dwCode			: UNICODE字符
 * @param - ptFontBitMap	: 位图信息
 * @return 			    	: 0 成功;其他 失败
 */
static int FreeTypeGetFontBitmap(uint32_t dwCode, PT_FontBitMap ptFontBitMap)
{
	int iError;
	int iPenX = ptFontBitMap->iCurOriginX;
	int iPenY = ptFontBitMap->iCurOriginY;
#if 0
	FT_Vector tPen;
	tPen.x = 0;
	tPen.y = 0;
	FT_Set_Transform(g_tFace, 0, &tPen);
#endif	
	/* 加载字符,得到字符位图*/
	iError = FT_Load_Char(g_tFace, dwCode, FT_LOAD_RENDER | FT_LOAD_MONOCHROME);
	if (iError)
	{
		DBG_PRINTF(DLOG_LVL_ERROR,DLOG_TAG,"FT_Load_Char error for code : 0x%x\n", dwCode);
		return -1;
	}
	/* 计算位图相对坐标*/
	ptFontBitMap->iXLeft    = iPenX + g_tSlot->bitmap_left;
	ptFontBitMap->iYTop     = iPenY - g_tSlot->bitmap_top;
	ptFontBitMap->iXMax     = ptFontBitMap->iXLeft + g_tSlot->bitmap.width;
	ptFontBitMap->iYMax     = ptFontBitMap->iYTop  + g_tSlot->bitmap.rows;
	ptFontBitMap->iBpp      = 1;
	ptFontBitMap->iPitch    = g_tSlot->bitmap.pitch;   
	ptFontBitMap->pucBuffer = g_tSlot->bitmap.buffer;  /* 字符位图数据 */
	
	ptFontBitMap->iNextOriginX = iPenX + g_tSlot->advance.x / 64;
	ptFontBitMap->iNextOriginY = iPenY;
	return 0;
}
/*
 * @description		    	: 设置字体大小
 * @param - dwFontSize		: 字体大小
 * @return 			    	: 0 成功;其他 失败
 */
static void FreeTypeSetFontSize(uint32_t dwFontSize)
{
	FT_Set_Pixel_Sizes(g_tFace, dwFontSize, 0);
}
/*
 * @description		    	: Freetype字体初始化
 * @param - 				: 无
 * @return 			    	: 0 成功;其他 失败
 */
int FreeTypeInit(void)
{
	return RegisterFontOpr(&g_tFreeTypeFontOpr);
}

